/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.marcelo.agro.productos.gui;

import java.net.URL;
import java.util.Collection;
import java.util.List;
import java.util.ResourceBundle;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ListChangeListener.Change;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javax.swing.SwingUtilities;
import org.marcelo.agro.core.DynamicLookup;
import org.marcelo.agro.core.api.IProductos;
import org.marcelo.agro.core.api.IProductos.MatchMode;
import org.marcelo.agro.entidades.*;
import org.marcelo.agro.entidades.eventos.ProductosEvent;
import org.marcelo.comun.database.PaginadorImpl;
import org.marcelo.comun.notificaciones.Notificaciones;
import org.openide.util.Lookup;
import org.openide.util.LookupEvent;
import org.openide.util.LookupListener;

/**
 *
 * @author marcelo
 * 
 */
public class ProductosController implements Initializable{
    
    
    @FXML TableView<Productos> tablaProductos;
    
    @FXML Button btnSiguiente;
    @FXML Button btnAnterior;
    @FXML Button btnInicio;
    @FXML Button btnFin;
    @FXML TextField txtBuscar;
       
    @FXML ComboBox<TipoProducto> cbTipoProductos;
    @FXML TableColumn<Productos, Integer> colID;
    @FXML TableColumn<Productos, String> colNombre;        
    @FXML TableColumn<Productos, Double> colPrecio;        
    @FXML TableColumn<Productos, String> colToxicidad;        
    @FXML TableColumn<Productos, Fabricante> colFabricante;        
    @FXML TableColumn<Productos, Registrante> colRegistrante;      
    @FXML TableColumn<Productos, TipoPresentacion> colTipoPresentacion;        
    @FXML TableColumn<Productos, Pais> colPais;
    
    @FXML TextField cantidadElementos;
    
    @FXML Label lblTotalItems;
    
    @FXML Label lblPagina;
            
            
    
    IProductos ip;
    
    PaginadorImpl<Productos> paginador;
    
    //Guardar los textos de Inicio
    
    String TEXTO_TOTAL_ITEMS;
    String TEXTO_PAGINA;
    Integer PAGINA_SIZE = 20;
    Integer PAGINA = 1;
    
    Productos actual;
      
       
    public ObservableList<TipoProducto> getTipoProductos(){
        ObservableList<TipoProducto> result = FXCollections.observableList(ip.getTiposProductos());
        return result;
    }
    
    public ObservableList<Productos> getProductos() {
        ObservableList<Productos> result = FXCollections.observableList(ip.getAll(Productos.class, paginador.desplazamiento(), paginador.limite()));
        return result;
    }

   @Override
    public void initialize(URL url, ResourceBundle rb) {
        ip = Lookup.getDefault().lookup(IProductos.class);
        paginador = new PaginadorImpl<Productos>(ip.getAll(),PAGINA, PAGINA_SIZE);
        assert btnAnterior != null : "fx:id=\"btnAnterior\" was not injected: check your FXML file 'listaProductos.fxml'.";
        assert btnFin != null : "fx:id=\"btnFin\" was not injected: check your FXML file 'listaProductos.fxml'.";
        assert btnInicio != null : "fx:id=\"btnInicio\" was not injected: check your FXML file 'listaProductos.fxml'.";
        assert btnSiguiente != null : "fx:id=\"btnSiguiente\" was not injected: check your FXML file 'listaProductos.fxml'.";
        assert cantidadElementos != null : "fx:id=\"cantidadElementos\" was not injected: check your FXML file 'listaProductos.fxml'.";
        assert cbTipoProductos != null : "fx:id=\"cbTipoProductos\" was not injected: check your FXML file 'listaProductos.fxml'.";
        assert colFabricante != null : "fx:id=\"colFabricante\" was not injected: check your FXML file 'listaProductos.fxml'.";
        assert colNombre != null : "fx:id=\"colNombre\" was not injected: check your FXML file 'listaProductos.fxml'.";
        assert colPais != null : "fx:id=\"colPais\" was not injected: check your FXML file 'listaProductos.fxml'.";
        assert colPrecio != null : "fx:id=\"colPrecio\" was not injected: check your FXML file 'listaProductos.fxml'.";
        assert colRegistrante != null : "fx:id=\"colRegistrante\" was not injected: check your FXML file 'listaProductos.fxml'.";
        assert colTipoPresentacion != null : "fx:id=\"colTipoPresentacion\" was not injected: check your FXML file 'listaProductos.fxml'.";
        assert colToxicidad != null : "fx:id=\"colToxicidad\" was not injected: check your FXML file 'listaProductos.fxml'.";
        assert lblPagina != null : "fx:id=\"lblPagina\" was not injected: check your FXML file 'listaProductos.fxml'.";
        assert lblTotalItems != null : "fx:id=\"lblTotalItems\" was not injected: check your FXML file 'listaProductos.fxml'.";
        assert tablaProductos != null : "fx:id=\"tablaProductos\" was not injected: check your FXML file 'listaProductos.fxml'.";
        assert txtBuscar != null : "fx:id=\"txtBuscar\" was not injected: check your FXML file 'listaProductos.fxml'.";
       
       
       cbTipoProductos.setItems(getTipoProductos());
       
       resultEvent = DynamicLookup.getDefault().lookupResult(ProductosEvent.class);
       resultEvent.addLookupListener(ll);
       
        
        TEXTO_TOTAL_ITEMS = lblTotalItems.getText();
        TEXTO_PAGINA = lblPagina.getText();
        configTabla();
        configBtn();
        configLabels();
        
    }
    
    private void configLabels(){
        lblTotalItems.setText(TEXTO_TOTAL_ITEMS + ": " + paginador.numeroElementos());
        lblPagina.setText(TEXTO_PAGINA+ ": " + paginador.pagina() + " de " +paginador.numeroPaginas());
    }
   
    public void enterPres() {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                Notificaciones.showMessageBox("Se presiono una tecla");
            }
        });
        
    }
    
    
    private void recargarTabla() {
        tablaProductos.getSelectionModel().clearSelection();
        tablaProductos.setItems(FXCollections.observableList(paginador.getPagina()));
        configBtn();
        configLabels();
    }
    
    public void siguiente(ActionEvent event) {
        paginador.siguiente();
        recargarTabla();
    }
    
    public void anterior(ActionEvent event){
        paginador.anterior();
        recargarTabla();
    }
    
    public void findProductos(ActionEvent event){
        String keyWord = txtBuscar.getText();
        List<Productos> result = ip.FindProductos(keyWord, new MatchMode(MatchMode.MATCH_MODES.ANYWARE), Boolean.TRUE);
//        if (!result.isEmpty()){
        paginador.setLista(result);
        recargarTabla();
    }
    
    
    private void configBtn(){
        btnSiguiente.setDisable(!paginador.tieneSiguiente());
        btnFin.setDisable(!paginador.tieneSiguiente());
        btnInicio.setDisable(!paginador.tieneAnterior());
        btnAnterior.setDisable(!paginador.tieneAnterior());
    }
    
    public void finLista(ActionEvent event){
        
        tablaProductos.setItems(FXCollections.observableList(paginador.fin()));
         configBtn();
         configLabels();
    }
    
    public void inicioLista(ActionEvent event){
        tablaProductos.setItems(FXCollections.observableList(paginador.inicio()));
        configBtn();
        configLabels();
    }
    
     private final ListChangeListener<Productos> tableSelectionChanged = new ListChangeListener<Productos>() {

        @Override
        public void onChanged(Change<? extends Productos> change) {
            updateLookup();
        }

        
    };
    
    private void updateLookup(){
        //Obtengo el seleccionado
        final Productos productoSeleccionado = getSelected(); 
        //si no es nulo lo cargo al lookup
        if (productoSeleccionado != null ) {
            DynamicLookup.getDefault().add(productoSeleccionado);
        }
        else {
            //si era nulo me fijo en el lookup
            actual = DynamicLookup.getDefault().lookup(Productos.class);
            if (actual !=null)
                //si ya se cargo algo al lookup lo quito
                DynamicLookup.getDefault().remove(actual);
        }
    }
    
    private Productos getSelected() {
        if (tablaProductos != null) {
            final List<Productos> productosList = tablaProductos.getSelectionModel().getSelectedItems();
            if (productosList.size() == 1) {
                final Productos result = productosList.get(0);
                return result;
            }
        }
        return null;
        
    }

    /**
     * MEtodo para configurar la tabla
     */
    private void configTabla() {
       tablaProductos.setItems(FXCollections.observableList(paginador.getPagina()));
              
       colNombre.setCellValueFactory(new PropertyValueFactory<Productos,String>("nombre")); 
       colPrecio.setCellValueFactory(new PropertyValueFactory<Productos,Double>("precio")); 
       colToxicidad.setCellValueFactory(new PropertyValueFactory<Productos,String>("toxicidad")); 
       colFabricante.setCellValueFactory(new PropertyValueFactory<Productos,Fabricante>("fabricante")); 
       colRegistrante.setCellValueFactory(new PropertyValueFactory<Productos,Registrante>("registrante")); 
       colPais.setCellValueFactory(new PropertyValueFactory<Productos,Pais>("paisOrigen")); 
       colTipoPresentacion.setCellValueFactory(new PropertyValueFactory<Productos,TipoPresentacion>("tipoPresentacion"));
       
       tablaProductos.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
       final ObservableList<Productos> seleccionTabla = tablaProductos.getSelectionModel().getSelectedItems();
       seleccionTabla.addListener(tableSelectionChanged);
    }
    
    //Detectar cambios de eventos en el Lookup
    Lookup.Result<ProductosEvent> resultEvent;
    //Listener para detectar el cambio 
    LookupListener ll = new LookupListener() {

        @Override
        public void resultChanged(LookupEvent ev) {
            //Si se agrega un nuevo elemeto debo volver a buscar los datos
            final LookupEvent ev2 = ev;
            Lookup.Result result = (Lookup.Result) ev2.getSource() ;
            Collection<? extends ProductosEvent> evts = result.allInstances();
            if (!evts.isEmpty()) {
                //Este codigo es ejecutado en el thread del swing
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        paginador.setLista(ip.getAll());
                        recargarTabla();
                    }
                });
            }
        }
    };
}
